﻿using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace TSharp.Core.Util.Config
{
    /// <summary>
    /// 用于序列化CData节点。不能包含<code >]] ></code>字符。
    /// by tangjingbo @2008/11/24
    /// </summary>
    /// 
    [Serializable]
    public class CDATA : IXmlSerializable, IEquatable<CDATA>, IComparable<CDATA>
    {
        private string _value;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public CDATA()
        {
        }

        /// <summary>
        /// 带参数构造函数
        /// </summary>
        /// <param name="value"></param>
        public CDATA(string value)
        {
            _value = value;
        }

        /// <summary>
        /// 
        /// </summary>
        public string Value
        {
            get { return _value; }
        }

        /// <summary>
        /// 长度
        /// </summary>
        public int Length
        {
            get { return _value.Length; }
        }

        #region IXmlSerializable interface

        /// <summary>
        /// 此方法是保留方法，请不要使用。在实现 IXmlSerializable 接口时，应从此方法返回 null（在 Visual Basic 中为 Nothing），如果需要指定自定义架构，应向该类应用 <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/>。
        /// </summary>
        /// <returns>
        ///   <see cref="T:System.Xml.Schema.XmlSchema"/>，描述由 <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/> 方法产生并由 <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/> 方法使用的对象的 XML 表示形式。
        /// </returns>
        XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }

        /// <summary>
        /// 从对象的 XML 表示形式生成该对象。
        /// </summary>
        /// <param name="reader">对象从中进行反序列化的 <see cref="T:System.Xml.XmlReader"/> 流。</param>
        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            /***** 如果此节点中包含有多个节点须使用此方法。**/
            _value = reader.ReadElementContentAsString();
            /* **********/
            //this.text = reader.ReadString();
            // reader.Read();
        }

        /// <summary>
        /// 将对象转换为其 XML 表示形式。
        /// </summary>
        /// <param name="writer">对象要序列化为的 <see cref="T:System.Xml.XmlWriter"/> 流。</param>
        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            writer.WriteCData(_value);
        }

        #endregion

        #region ToString()

        /// <summary>
        /// 重写 获取CData节点的 内容
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this != null ? _value : string.Empty;
        }

        #endregion

        #region implicit operator

        /// <summary>
        /// 将 CDATA 对象隐式转换成 内容 字符串。
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static implicit operator string(CDATA element)
        {
            return (element == null) ? null : element._value;
        }

        /// <summary>
        /// 将 内容 对象隐式转换成 CDATA 字符串。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static implicit operator CDATA(string value)
        {
            return new CDATA(value);
        }

        /// <summary>
        /// 将 内容 对象隐式转换成 CDATA 字符串。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static implicit operator CDATA(Int32 value)
        {
            return new CDATA(value.ToString());
        }

        /// <summary>
        /// 将 内容 对象隐式转换成 CDATA 字符串。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static implicit operator CDATA(Int64 value)
        {
            return new CDATA(value.ToString());
        }

        /// <summary>
        /// 将 内容 对象隐式转换成 CDATA 字符串。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static implicit operator CDATA(double value)
        {
            return new CDATA(value.ToString());
        }

        #endregion

        #region IEquatable<CDATA> 成员

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(CDATA other)
        {
            return (other != null) ? _value.Equals(other._value) : false;
        }

        #endregion

        #region IComparable<CDATA> 成员

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(CDATA other)
        {
            return (other != null) ? _value.CompareTo(other._value) : 1;
        }

        #endregion
    }
}